﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Diagnostics;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Razor;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.FileProviders;
using MvcSample.Data;
using MvcSample.Data.Core;
using MvcSample.Filters;
using MvcSample.Infrastructure.Filters;
using MvcSample.Middlewares;
using MvcSample.ModelBinders;
using MvcSample.Services;
using MvcSample.ViewLocationExpanders;
using WebMarkupMin.AspNetCore2;

namespace MvcSample
{
    public class Startup
    {
        public IConfiguration Configuration;
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            var myConn = Configuration.GetConnectionString("DefaultConnection");
            services.AddDbContextPool<ApplicationContext>(opt => opt.UseSqlServer(myConn));

            services.AddDbContext<ApplicationDbContext>(opt => opt.UseSqlServer(myConn, e => e.MigrationsAssembly(nameof(MvcSample))));
            services.AddIdentity<ApplicationUser, IdentityRole>()
                .AddDefaultUI()
                .AddEntityFrameworkStores<ApplicationDbContext>();

            services.Configure<RazorViewEngineOptions>(opt =>
            {
                //opt.ViewLocationExpanders.Insert(0,new FeatureViewLocationExpander());
                opt.ViewLocationExpanders.Insert(0, new ThemeViewLocationExpander());
            });
            services.AddScoped<Blog, Blog>();
            services.AddScoped<IStudentService, StudentService>();
            services.AddMvc(
                cfg =>
            {
                //    opt.Filters.Add<GlobalModelValidationFilter>();
                //    opt.Filters.Add<GlobalLogExceptionFilter>();
                cfg.ModelBinderProviders.Insert(0, new RmbModelBinderProvider());
                cfg.Filters.Add<AutoValidateAntiforgeryTokenAttribute>();
                cfg.Filters.Add<CustomResourceFilter>();
                cfg.CacheProfiles.Add("default", new CacheProfile() { Duration = 60, Location = ResponseCacheLocation.Client, NoStore = false });
                cfg.CacheProfiles.Add("never", new CacheProfile() { Duration = 0, Location = ResponseCacheLocation.Client, NoStore = true });
            })
            .AddViewLocalization(opt =>
            {
                opt.ResourcesPath = "Resources";
            });

            services.AddLocalization(opt =>
            {
            });
            services.Configure<RequestLocalizationOptions>(opt =>
            {
                var supportedCultures = new List<CultureInfo>()
                {
                     new CultureInfo("zh-cn"),
                     new CultureInfo("en-us"),
                     new CultureInfo("en-gb")
                };
                opt.DefaultRequestCulture = new Microsoft.AspNetCore.Localization.RequestCulture("zh-cn");
                opt.SupportedCultures = supportedCultures;
                opt.SupportedUICultures = supportedCultures;
            });
            services.AddMemoryCache();
            services.AddDistributedRedisCache(opt =>
            {
                opt.Configuration = "";
                opt.InstanceName = "";
            });
            services.AddResponseCaching();
            services.AddResponseCompression();
            services.AddWebMarkupMin(opt =>
            {
                opt.AllowCompressionInDevelopmentEnvironment = true;
                opt.AllowMinificationInDevelopmentEnvironment = true;
            })
            .AddHtmlMinification(opt =>
            {
                opt.MinificationSettings.RemoveEmptyAttributes = true;
                opt.MinificationSettings.RemoveTagsWithoutContent = true;
                opt.MinificationSettings.RemoveRedundantAttributes = true;
                opt.MinificationSettings.RemoveHttpProtocolFromAttributes = true;
                opt.MinificationSettings.RemoveHttpsProtocolFromAttributes = true;
            });
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            app.UserLogException();
            //app.UseExceptionHandler(opt =>
            //{
            //    opt.Use(async (ctx, next) =>
            //    {
            //        await ctx.Response.WriteAsync("Internal Error.");
            //        await next.Invoke();
            //        await ctx.Response.WriteAsync("Internal Error.");
            //    });
            //});
            app.UseStaticFiles();
            app.UseStaticFiles(new StaticFileOptions()
            {
                FileProvider = new PhysicalFileProvider(Path.Combine(env.ContentRootPath, "node_modules")),
                RequestPath = "/node_modules"
            });
            app.UseAuthentication();
            app.UseResponseCaching();
            app.UseResponseCompression();
            app.UseWebMarkupMin();
            //app.UseMvcWithDefaultRoute();
            app.UseMvc(routes =>
            {
                routes.MapRoute("area", "{area}/{controller=Default}/{action=Index}/{id?}");
                routes.MapRoute("default", "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }
}
